package com.plian.system.service.im.impl;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.BigDecimalUtil;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.DateUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.baseinfo.ValueSetConstant;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.dto.im.MainProjectSituationDTO;
import com.plian.system.entity.im.MainProjectSituation;
import com.plian.system.mapper.im.MainProjectSituationMapper;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.service.bt.baseinfo.BaseInfoService;
import com.plian.system.service.im.IMainProjectSituationService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.vo.im.MainProjectSituationVO;
import com.plian.system.vo.im.MainProjectStatisticsVO;
import com.plian.system.vo.report.HeaderVO;
import com.plian.system.vo.report.ReportReturnVO;
import com.plian.system.vo.report.ReportVO;
import com.plian.system.wrapper.im.MainProjectSituationWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class MainProjectSituationServiceImpl extends BaseServiceImpl<MainProjectSituationMapper, MainProjectSituation> implements IMainProjectSituationService {

	private BaseInfoService baseInfoService;

	private OrgzationDao orgzationDao;

	private MainProjectSituationWrapper mainProjectSituationWrapper;

	private IOrgService orgService;

	@Override
	public boolean saveOrUpdate(MainProjectSituation mainProjectSituation) {
		return super.saveOrUpdate(mainProjectSituation);
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean deleteLogic(List<Long> ids) {
		for (Long id : ids) {
			MainProjectSituation mainProjectSituation = getById(id);
			if (mainProjectSituation == null) {
				return false;
			}
		}
		return super.deleteLogic(ids);
	}

	@Override
	public ReportReturnVO statisticsByNature(MainProjectSituationDTO mainProjectSituationDTO) {

		/**
		 * 初始化项目性质分类数组
		 */
		List<MainProjectStatisticsVO> initList = natureInit(mainProjectSituationDTO.getProjectNatureIds());

		/**
		 * 填报年月为空时默认为当前月份
		 */
		if (StringUtil.isBlank(mainProjectSituationDTO.getFilingMonth())){
			mainProjectSituationDTO.setFilingMonth(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH));
		}

		/**
		 * 按项目性质分类
		 */
		Map<String, List<MainProjectStatisticsVO>> map = baseMapper.statisticsByNature(mainProjectSituationDTO.getFillingUnitIds(),
				mainProjectSituationDTO.getProjectNatureIds(), mainProjectSituationDTO.getFilingMonth())
				.stream().collect(Collectors.groupingBy(MainProjectStatisticsVO::getProjectNatureId));
		List<MainProjectStatisticsVO> data = new ArrayList<>();

		/**
		 * 总计
		 */
		MainProjectStatisticsVO end = MainProjectStatisticsVO.builder().index("合计").build();
		for (MainProjectStatisticsVO vo : initList){
			data.add(vo);
			if (map.containsKey(vo.getProjectNatureId())){
				/**
				 * 小计
				 */
				MainProjectStatisticsVO initVO = MainProjectStatisticsVO.builder().index("小计").build();
				List<MainProjectStatisticsVO> list = map.get(vo.getProjectNatureId());

				boolean flag = true;
				for (MainProjectStatisticsVO result : list){
					/**
					 * 第一次进来 将result 值赋予初始化的值
					 */
					if (result.getCompletionRate() != null){
						result.setCompletionRate(result.getCompletionRate().setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					if (flag){
						String projectNatureName = data.get(data.size()-1).getProjectNatureName();
						result.setProjectNatureName(projectNatureName);
						result.setIndex(vo.getIndex());
						BeanUtils.copyProperties(result, vo);
						flag = false;
					}else {
						data.add(result);
					}
					initVO.setPlanTotalInvestment(BigDecimalUtil.add(initVO.getPlanTotalInvestment(), result.getPlanTotalInvestment()));
					initVO.setLastCompleteInvestment(BigDecimalUtil.add(initVO.getLastCompleteInvestment(), result.getLastCompleteInvestment()));
					initVO.setCompleteInvestment(BigDecimalUtil.add(initVO.getCompleteInvestment(), result.getCompleteInvestment()));
					initVO.setAllCompleteInvestment(BigDecimalUtil.add(initVO.getAllCompleteInvestment(), result.getAllCompleteInvestment()));

				}
				initVO.setCompletionRate(BigDecimalUtil.divide(
						BigDecimalUtil.add(initVO.getLastCompleteInvestment(), initVO.getCompleteInvestment()),
						initVO.getPlanTotalInvestment(), 2, BigDecimal.ROUND_HALF_UP, 100));
				data.add(initVO);
				end.setPlanTotalInvestment(BigDecimalUtil.add(initVO.getPlanTotalInvestment(), end.getPlanTotalInvestment()));
				end.setLastCompleteInvestment(BigDecimalUtil.add(initVO.getLastCompleteInvestment(), end.getLastCompleteInvestment()));
				end.setCompleteInvestment(BigDecimalUtil.add(initVO.getCompleteInvestment(), end.getCompleteInvestment()));
				end.setAllCompleteInvestment(BigDecimalUtil.add(initVO.getAllCompleteInvestment(), end.getAllCompleteInvestment()));

			}else {
				data.add(MainProjectStatisticsVO.builder().index("小计").build());
			}
		}
		end.setCompletionRate(BigDecimalUtil.divide(
				BigDecimalUtil.add(end.getLastCompleteInvestment(), end.getCompleteInvestment()),
				end.getPlanTotalInvestment(), 2, BigDecimal.ROUND_HALF_UP, 100));
		data.add(end);

		ReportReturnVO reportReturnVO = new ReportReturnVO();

		ReportVO reportVO = new ReportVO();

		reportVO
				.addHeader(HeaderVO.builder().key("index").title("序号").build())
				.addHeader(HeaderVO.builder().key("projectNatureName").title("项目类别").build())
				.addHeader(HeaderVO.builder().key("filingUnitName").title("企业名称").build())
				.addHeader(HeaderVO.builder().key("projectName").title("项目名称").build())
				.addHeader(HeaderVO.builder().key("planTotalInvestment").title("年度计划").build())
				.addHeader(HeaderVO.builder().key("lastCompleteInvestment").title("至上月底完成年度投资（万元）").build())
				.addHeader(HeaderVO.builder().key("completeInvestment").title("本月完成投资（万元）").build())
				.addHeader(HeaderVO.builder().key("allCompleteInvestment").title("本年完成投资（万元）").build())
				.addHeader(HeaderVO.builder().key("mainProgress").title("主要形象进度").build())
				.addHeader(HeaderVO.builder().key("problem").title("存在的问题").build())
				.addHeader(HeaderVO.builder().key("completionRate").title("完成率%").build());
		reportVO.setData(data);
		reportReturnVO.setGrids(reportVO);
		return reportReturnVO;
	}

	@Override
	public ReportReturnVO statisticsByUnit(MainProjectSituationDTO mainProjectSituationDTO) {
		/**
		 * 填报年月为空时默认为当前月份
		 */
		if (StringUtil.isBlank(mainProjectSituationDTO.getFilingMonth())){
			mainProjectSituationDTO.setFilingMonth(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH));
		}
		/**
		 * 初始化项目性质分类数组
		 */
		List<MainProjectStatisticsVO> initList = unitInit(mainProjectSituationDTO.getFillingUnitIds(), mainProjectSituationDTO.getFilingMonth());


		/**
		 * 按项目性质分类
		 */
		Map<String, List<MainProjectStatisticsVO>> map = baseMapper.statisticsByUnit(mainProjectSituationDTO.getFillingUnitIds(), mainProjectSituationDTO.getFilingMonth())
				.stream().collect(Collectors.groupingBy(MainProjectStatisticsVO::getFilingUnitId));
		List<MainProjectStatisticsVO> data = new ArrayList<>();

		/**
		 * 总计
		 */
		if (CollectionUtil.isNotEmpty(initList)){
			MainProjectStatisticsVO end = MainProjectStatisticsVO.builder().index("合计").build();
			for (MainProjectStatisticsVO vo : initList){
				if (map.containsKey(vo.getFilingUnitId())){
					/**
					 * 小计
					 */
					MainProjectStatisticsVO initVO = MainProjectStatisticsVO.builder().index("小计").build();
					List<MainProjectStatisticsVO> list = map.get(vo.getFilingUnitId());

					boolean flag = true;
					for (MainProjectStatisticsVO result : list){
						if (flag){
							/**
							 * 第一次进来 将result 值赋予初始化的值
							 */
							String filingUnitName = vo.getFilingUnitName();
							result.setFilingUnitName(filingUnitName);
							result.setIndex(vo.getIndex());
							flag = false;
						}
						initVO.setPlanTotalInvestment(BigDecimalUtil.add(initVO.getPlanTotalInvestment(), result.getPlanTotalInvestment()));
						initVO.setLastCompleteInvestment(BigDecimalUtil.add(initVO.getLastCompleteInvestment(), result.getLastCompleteInvestment()));
						initVO.setCompleteInvestment(BigDecimalUtil.add(initVO.getCompleteInvestment(), result.getCompleteInvestment()));
						initVO.setAllCompleteInvestment(BigDecimalUtil.add(initVO.getAllCompleteInvestment(), result.getAllCompleteInvestment()));
						if(result.getCompletionRate() != null){
							result.setCompletionRate(result.getCompletionRate().setScale(2, BigDecimal.ROUND_HALF_UP));
						}
						data.add(result);
					}
					initVO.setCompletionRate(BigDecimalUtil.divide(
							BigDecimalUtil.add(initVO.getLastCompleteInvestment(), initVO.getCompleteInvestment()),
							initVO.getPlanTotalInvestment(), 2, BigDecimal.ROUND_HALF_UP, 100));
					data.add(initVO);
					end.setPlanTotalInvestment(BigDecimalUtil.add(initVO.getPlanTotalInvestment(), end.getPlanTotalInvestment()));
					end.setLastCompleteInvestment(BigDecimalUtil.add(initVO.getLastCompleteInvestment(), end.getLastCompleteInvestment()));
					end.setCompleteInvestment(BigDecimalUtil.add(initVO.getCompleteInvestment(), end.getCompleteInvestment()));
					end.setAllCompleteInvestment(BigDecimalUtil.add(initVO.getAllCompleteInvestment(), end.getAllCompleteInvestment()));
					end.setCompletionRate(BigDecimalUtil.add(initVO.getCompletionRate(), end.getCompletionRate()));
				}else {
					data.add(vo);
					data.add(MainProjectStatisticsVO.builder().index("小计").build());
				}
			}
			end.setCompletionRate(BigDecimalUtil.divide(
					BigDecimalUtil.add(end.getLastCompleteInvestment(), end.getCompleteInvestment()),
					end.getPlanTotalInvestment(), 2, BigDecimal.ROUND_HALF_UP, 100));
			data.add(end);
		}

		ReportReturnVO reportReturnVO = new ReportReturnVO();
		ReportVO reportVO = new ReportVO();
		reportVO
				.addHeader(HeaderVO.builder().key("index").title("序号").build())
				.addHeader(HeaderVO.builder().key("filingUnitName").title("企业名称").build())
				.addHeader(HeaderVO.builder().key("projectName").title("项目名称").build())
				.addHeader(HeaderVO.builder().key("projectNatureName").title("项目类别").build())
				.addHeader(HeaderVO.builder().key("planTotalInvestment").title("年度计划").build())
				.addHeader(HeaderVO.builder().key("lastCompleteInvestment").title("至上月底完成年度投资").build())
				.addHeader(HeaderVO.builder().key("completeInvestment").title("本月完成投资").build())
				.addHeader(HeaderVO.builder().key("allCompleteInvestment").title("本年完成投资").build())
				.addHeader(HeaderVO.builder().key("mainProgress").title("主要形象进度").build())
				.addHeader(HeaderVO.builder().key("problem").title("存在的问题").build())
				.addHeader(HeaderVO.builder().key("completionRate").title("完成率%").build());
		reportVO.setData(data);
		reportReturnVO.setGrids(reportVO);
		return reportReturnVO;
	}



	@Override
	public void write(List<MainProjectSituation> mainProjectSituations, ExcelWriter excelWriter, WriteSheet writeSheet, FillConfig fillConfig) {
		List<MainProjectSituationVO> mainProjectSituationVOS = mainProjectSituationWrapper.entityToVO(mainProjectSituations);
		if (CollectionUtil.isNotEmpty(mainProjectSituationVOS)){
			MainProjectSituationVO subTotal = new MainProjectSituationVO();
			subTotal.setProjectName("合计");
			for (MainProjectSituationVO situationVO : mainProjectSituationVOS){
				subTotal.setPlanTotalInvestment(BigDecimalUtil.add(subTotal.getPlanTotalInvestment(), situationVO.getPlanTotalInvestment()));
				subTotal.setLastCompleteInvestment(BigDecimalUtil.add(subTotal.getLastCompleteInvestment(), situationVO.getLastCompleteInvestment()));
				subTotal.setCompleteInvestment(BigDecimalUtil.add(subTotal.getCompleteInvestment(), situationVO.getCompleteInvestment()));
			}
			mainProjectSituationVOS.add(subTotal);
		}
		excelWriter.fill(new FillWrapper("main", mainProjectSituationVOS), fillConfig, writeSheet);
	}

	@Override
	public boolean deleteByParentId(List<Long> ids) {
		LambdaQueryWrapper<MainProjectSituation> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(MainProjectSituation::getEffectiveInvestmentId, ids);
		List<MainProjectSituation> mainProjectSituations = list(queryWrapper);
		if (CollectionUtil.isNotEmpty(mainProjectSituations)){
			return deleteLogic(mainProjectSituations.stream().map(MainProjectSituation::getId).collect(Collectors.toList()));
		}
		return true;
	}

	@Override
	public ReportReturnVO summaryDetail(MainProjectSituationDTO mainProjectSituationDTO) {
		mainProjectSituationDTO.setFilingMonth(mainProjectSituationDTO.getFillingMonth());
		/**
		 * 填报年月为空时默认为当前月份
		 */
		if (StringUtil.isBlank(mainProjectSituationDTO.getFilingMonth())){
			mainProjectSituationDTO.setFilingMonth(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH));
		}
		List<MainProjectStatisticsVO> results = baseMapper.summaryDetail(mainProjectSituationDTO.getFillingUnitIds(), mainProjectSituationDTO.getFilingMonth());
		if (CollectionUtil.isNotEmpty(results)){
			MainProjectStatisticsVO end = MainProjectStatisticsVO.builder().projectName("合计").build();
			for (MainProjectStatisticsVO vo : results){
				end.setPlanTotalInvestment(BigDecimalUtil.add(end.getPlanTotalInvestment(), vo.getPlanTotalInvestment()));
				end.setAllCompleteInvestment(BigDecimalUtil.add(end.getAllCompleteInvestment(), vo.getAllCompleteInvestment()));
			}
			end.setCompletionRate(BigDecimalUtil.divide(end.getAllCompleteInvestment(), end.getPlanTotalInvestment(), 2, BigDecimal.ROUND_HALF_UP, 100));
			results.add(0, end);
		}

		ReportReturnVO reportReturnVO = new ReportReturnVO();
		ReportVO reportVO = new ReportVO();
		reportVO
				.addHeader(HeaderVO.builder().key("index").title("序号").build())
				.addHeader(HeaderVO.builder().key("projectName").title("项目名称").build())
				.addHeader(HeaderVO.builder().key("planTotalInvestment").title("年度计划").build())
				.addHeader(HeaderVO.builder().key("allCompleteInvestment").title("本年完成投资").build())
				.addHeader(HeaderVO.builder().key("completionRate").title("完成率").build());
		reportVO.setData(results);
		reportReturnVO.setGrids(reportVO);
		return reportReturnVO;
	}


	/**
	 * 项目性质
	 * @param projectNatureIds
	 * @return
	 */
	private List<MainProjectStatisticsVO> natureInit(List<String> projectNatureIds){
		Map<String, String> projectMap = baseInfoService.getChildMap(ValueSetConstant.PROJECT_NATURE);
		List<MainProjectStatisticsVO> initList = new ArrayList<>();
		if (CollectionUtil.isEmpty(projectNatureIds)){
			initList = projectMap.entrySet().stream().map(e -> MainProjectStatisticsVO.builder()
					.projectNatureName(e.getValue()).projectNatureId(e.getKey()).build()).collect(Collectors.toList());
		}else {
			for (String projectNatureId : projectNatureIds){
				initList.add(MainProjectStatisticsVO.builder().projectNatureName(projectMap.get(projectNatureId)).projectNatureId(projectNatureId).build());
			}
		}
		initList = initList.stream().sorted(Comparator.comparing(MainProjectStatisticsVO::getProjectNatureId)).collect(Collectors.toList());

		for (int i = 0; i < initList.size(); i++){
			MainProjectStatisticsVO init = initList.get(i);
			init.setIndex(String.valueOf(i+1));
		}
		return initList;
	}

	/**
	 * 一级企业
	 * @param filingUnitIds
	 * @return
	 */
	private  List<MainProjectStatisticsVO> unitInit(List<String> filingUnitIds, String countDate) {
		List<PageData> firstCompanyList = new ArrayList<>();
		try {
			if (orgService.getDTFlag(countDate)){
				firstCompanyList = orgzationDao.findGZWUnitsFilterDT();
			}else {
				firstCompanyList = orgzationDao.findGZWUnits();
			}
		}catch (Exception e){
            log.error("获取集团失败-->" + e);
		}

		List<MainProjectStatisticsVO> init = new ArrayList<>();

		if (CollectionUtil.isEmpty(firstCompanyList)){
			return init;
		}

		int index = 1;
		if (CollectionUtil.isEmpty(filingUnitIds)){
			for (PageData pd : firstCompanyList){
				init.add(MainProjectStatisticsVO.builder().index(String.valueOf(index)).filingUnitId((String)pd.get("id")).filingUnitName((String)pd.get("name")).build());
				index++;
			}
		}else {
			filingUnitIds = filingUnitIds.stream().distinct().collect(Collectors.toList());
			for (String filingUnitId : filingUnitIds){
				for (PageData pd : firstCompanyList){
					if (filingUnitId.equals(pd.get("id"))){
						init.add(MainProjectStatisticsVO.builder().index(String.valueOf(index)).filingUnitId(filingUnitId).filingUnitName((String)pd.get("name")).build());
						index++;
						break;
					}
				}

			}
		}
		return init;
	}


}
